package org.dei.perla.test.llqruntime.simulator;

import org.dei.perla.parser.grammar.*;
import org.dei.perla.parser.statements.*;
import org.dei.perla.parser.expressions.*;
import org.dei.perla.sys.environments.ActiveSession;
import org.dei.perla.sys.environments.Environment;
import org.dei.perla.sys.environments.LLEnvironment;
import org.dei.perla.sys.environments.QueryAnalyzer;
import org.dei.perla.sys.query.llqruntime.datacollection.LLStack;
import org.dei.perla.sys.registry.Registry;
import org.dei.perla.utils.logger.*;
import org.dei.perla.utils.logger.LogRecord.Verbosity;
import java.io.*;
import java.util.*;

public class RunSimulator extends Thread{

	static ArrayList<FileInputStream> inputs = new ArrayList<FileInputStream>();
	static ArrayList<Query> parsedqueries = new ArrayList<Query>();
	static int frequenza = 0;
	
	/**
	 * @param args
	 * @throws InterruptedException 
	 */
	public static void main(String[] args) throws InterruptedException {
		
		doSetup();
		System.out.println("SETUP della \"rete\" eseguito");
		askForQueries();
		System.out.println("RICHIESTA completata");
		parse();
		System.out.println("CHECK INIZIALE");
		preliminaryCheck();
		System.out.println("PRESS ANY KEY TO SIMULATE");
		try {
			System.in.read();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		simulate();
	}
	
	private static void doSetup() {
		//un pò di logger
		ILogger logger = new ConsoleLogger();
		logger.setVerbosity(Verbosity.High);
		logger.start();
		QueryAnalyzer.getInstance().loggerAttach(logger);
	
		
		//"carico" i sensori
		//primo sensore
		DeviceMockup d1 = new DeviceMockup();
		d1.addCapability("temp", ConstantFloat.class);
		d1.addCapability("press", ConstantFloat.class);
		
		//secondo sensore
		DeviceMockup d2 = new DeviceMockup();
		d2.addCapability("temp", ConstantFloat.class);
		
		//li aggancio agli FPC adhoc
		
		FPCmockup f1 = new FPCmockup("FPC A",null);
		FPCmockup f2 = new FPCmockup("FPC B",null);
		
		//avviso il registry (veci della FPC-FACTORY)
		
		Registry.registerThisFPC(f1);
		Registry.registerThisFPC(f2);
	}	
	
	
	private static void preliminaryCheck() {
		
		System.out.println("TOTALE   :"+ActiveSession.getEnvironmentsNumber());
		
		Iterator<Environment> tIterator = ActiveSession.getActiveEnvironments();
		int i = 0;
				
		while (tIterator.hasNext()) {
			Environment tEnvs= tIterator.next();
			System.out.println(".::Query "+i+" :"+tEnvs.getRepresentedQuery().toString());
			
			for (LLStack tStack : ((LLEnvironment) tEnvs).getActiveLLStacks()) {
				System.out.println(tStack.getDataCollector().getLLDataCollectionInfo().getLocalBuffer().hashCode());
			}
			System.out.println("========================================================");
	}
		
	}
	
	private static void askForQueries() {
		
		Scanner scanner = new Scanner(System.in);
		System.out.println(".::Inserire nomi file delle query, per ultima frequenza iniezione.");
		String[] splitted = scanner.nextLine().split("( |\t)+");
		System.out.println(".::Lunghezza array (debug)"+splitted.length);
		
		for (int i=0; i<splitted.length-1;i++) {
			try {
				inputs.add(new FileInputStream("test" + File.separatorChar + "registryquery"+ File.separatorChar + splitted[i]+".txt"));
			} catch (FileNotFoundException e) {
				System.out.println(".::File "+splitted[i]+" non trovato/errore");
			}
		}
		frequenza = new Integer(splitted[splitted.length-1]).intValue();

		if (splitted.length==2) frequenza = 0; //solo una queri, frequenza non valida
		System.out.println(".::Ricevute query, la frequenza e' :"+frequenza);
	}
	
	private static void parse() {
		
		boolean firststart = false;
		
		
		for (FileInputStream tFile : inputs) {
		
			if (firststart == false) {
				firststart = true;
				new Parser(tFile);
			}else Parser.ReInit(tFile);
			
			try {
				
				Query tQuery = Parser.StatementSequence();
				QueryAnalyzer.registerQuery(tQuery);
				
						
			} 
			catch (ParseException e) {
				
				System.out.println("Errore di parsing file : "+tFile.toString());
				System.out.println(e.getMessage());
			}
			
		}
	}
	
	private static void simulate() throws InterruptedException {
		for (Environment t : ActiveSession.getEnvironments()) {
			t.start();
			sleep(frequenza*1000);
		}
	}
}

